package com.github.data_manage.util

import cn.hutool.core.date.DateField
import cn.hutool.core.date.DateTime
import cn.hutool.core.date.DateUtil
import cn.idev.excel.converters.Converter
import cn.idev.excel.converters.ReadConverterContext
import cn.idev.excel.converters.WriteConverterContext
import cn.idev.excel.enums.CellDataTypeEnum
import cn.idev.excel.metadata.data.WriteCellData
import com.github.data_manage.common.DAY_FORMATTER
import org.springframework.util.StringUtils
import java.math.RoundingMode
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.ZoneId
import java.util.*

/**
 *@author CHN
 *@since 2024-08-08 20:14
 */
class LocalDateConvert : Converter<LocalDate?> {
    override fun supportJavaTypeKey(): Class<LocalDate> {
        return LocalDate::class.java
    }

    override fun supportExcelTypeKey(): CellDataTypeEnum {
        return CellDataTypeEnum.STRING
    }

    @Throws(Exception::class)
    override fun convertToExcelData(context: WriteConverterContext<LocalDate?>): WriteCellData<*> {
        if (context.value != null) {
            return WriteCellData<String>(context.value!!.format(DAY_FORMATTER))
        }
        return WriteCellData<String>("")
    }

    override fun convertToJavaData(context: ReadConverterContext<*>?): LocalDate? {
        val readCellData = context!!.readCellData
        if (Objects.requireNonNull<CellDataTypeEnum>(readCellData.type) == CellDataTypeEnum.NUMBER) {
            val numberValue = readCellData.numberValue.setScale(0, RoundingMode.HALF_UP).toLong()
            return LocalDate.of(1900, 1, 1).plusDays(numberValue)
        } else {
            val stringValue = readCellData.stringValue
            if (StringUtils.hasText(stringValue)) {
                val dateTime: DateTime = DateUtil.parse(stringValue as CharSequence)
                val hour: Int = dateTime.getField(DateField.HOUR)
                val minute: Int = dateTime.getField(DateField.MINUTE)
                val second: Int = dateTime.getField(DateField.SECOND)
                if (hour == 0 && minute == 0 && second == 0) {
                    return LocalDate.of(
                        dateTime.getField(DateField.YEAR),
                        dateTime.getField(DateField.MONTH) + 1,
                        dateTime.getField(DateField.DAY_OF_MONTH)
                    )
                }
                return LocalDateTime.ofInstant(dateTime.toInstant(), ZoneId.systemDefault()).toLocalDate()
            }
        }
        return LocalDate.now()
    }
}
